/*
 * BestFit2.cc
 *
 *  Created on: Apr 18, 2013
 *      Author: erik
 */

#include "BestFit2.h"
#include "asserts.h"

// Iemand levert een gebied weer in
void BestFit2::free(Area *ap)
{
	require(ap != 0);

	if (cflag) {
		// EXPENSIVE: check for overlap with all registered free areas
		for(ALiterator  i = areas.begin() ; i != areas.end() ; ++i) {
			check(!ap->overlaps(*i));    // the sanity check
		}
	}
	// Find the right place to insert ap, keeping the list sorted by address
	for (ALiterator  i = areas.begin() ; i != areas.end() ; )
	{
		Area  *bp = *i;							// match new ap with existing bp ...

		// Does older area bp match new free area ap?
		if (bp->getBase() == (ap->getBase() + ap->getSize())) {
			// Yes, bp matches with ap ...	[ap directly before bp]
			areas.erase(i);	// remove bp from the list
			ap->join(bp);						// append area bp to ap (and destroy bp)
			++mergers;							// update statistics
			this->insertArea(ap);
			return;
		}
		else if (ap->getBase() == (bp->getBase() + bp->getSize())) {
			// Yes, ap matches with bp ... [ap directly after bp]
			areas.erase(i);	// remove bp from the list
			bp->join(ap);						// append area ap to bp (and destroy ap)
			++mergers;							// update statistics
			this->insertArea(bp);
			return;
		}
			++i;								// move on to next area in the freelist
	}

	this->insertArea(ap);

}
